package org.fujay.langchain4jserver.application.assembler;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.fujay.langchain4jserver.application.dto.AppConfigHistoryDTO;
import org.fujay.langchain4jserver.application.dto.ApplicationDetailDTO;
import org.fujay.langchain4jserver.application.dto.ApplicationSummaryDTO;
import org.fujay.langchain4jserver.domain.application.aggregate.AppAggregate;
import org.fujay.langchain4jserver.domain.application.entity.App;
import org.fujay.langchain4jserver.domain.application.entity.AppConfigHistory;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 应用聚合 与 DTO 之间的转换器
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ApplicationAssembler {

    public static ApplicationSummaryDTO toSummaryDTO(final AppAggregate aggregate) {
        if (aggregate == null) return null;
        App app = aggregate.getApp(); // Get the root entity
        ApplicationSummaryDTO dto = new ApplicationSummaryDTO();
        dto.setId(app.getId().value());
        dto.setAppName(app.getAppName());
        dto.setAppDesc(app.getAppDesc());
        dto.setCreatedAt(app.getCreateTime() != null ? app.getCreateTime().toString() : null);
        dto.setUpdatedAt(app.getUpdateTime() != null ? app.getUpdateTime().toString() : null);
        return dto;
    }

    public static List<ApplicationSummaryDTO> toSummaryDTOList(final List<AppAggregate> aggregates) {
        if (aggregates == null) return List.of();
        return aggregates.stream().map(ApplicationAssembler::toSummaryDTO).collect(Collectors.toList());
    }

    public static ApplicationDetailDTO toDetailDTO(final @NonNull AppAggregate aggregate) {
        App app = aggregate.getApp();
        ApplicationDetailDTO dto = new ApplicationDetailDTO();
        dto.setId(app.getId().value());
        dto.setAppName(app.getAppName());
        dto.setAppDesc(app.getAppDesc());
        dto.setModelId(app.getModelId().value());
        dto.setUseKnowledgeBase(app.isUseKnowledgeBase());
        dto.setKnowledgeBaseId(
                app.getKnowledgeBaseId() != null ? app.getKnowledgeBaseId().value() : null);
        dto.setCurrentVersion(aggregate.getCurrentVersion().value());
        dto.setCreatedAt(app.getCreateTime() != null ? app.getCreateTime().toString() : null);
        dto.setUpdatedAt(app.getUpdateTime() != null ? app.getUpdateTime().toString() : null);
        dto.setConfigHistory(toConfigHistoryDTOList(aggregate.getConfigHistory()));
        return dto;
    }

    public static AppConfigHistoryDTO toConfigHistoryDTO(final AppConfigHistory history) {
        if (history == null) return null;
        AppConfigHistoryDTO dto = new AppConfigHistoryDTO();
        dto.setVersion(history.getVersion().value());
        dto.setConfigSnapshot(history.getConfigSnapshot()); // Assuming snapshot is transferable
        dto.setChangeDescription(history.getChangeDescription());
        dto.setChangedBy(history.getChangedBy());
        dto.setChangeTime(history.getChangeTime() != null ? history.getChangeTime().toString() : null);
        return dto;
    }

    public static List<AppConfigHistoryDTO> toConfigHistoryDTOList(final List<AppConfigHistory> historyList) {
        if (historyList == null) return List.of();
        return historyList.stream().map(ApplicationAssembler::toConfigHistoryDTO).collect(Collectors.toList());
    }

    // TODO: Methods to convert Request DTOs to domain parameters if needed

}
